#
#   Spawner.py
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; version 2 of the License.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   Copyright
#   Author: Salvatore S. Gionfriddo
#   Contributors: Nicholas F. Hoover
#   Created: 2007.07.02
#   Last Modified: 2007.07.12
#

import random


class Spawner:
    def __init__(self, spawner, perSpawn, ticsPerSpawn):
        self.spawner = spawner
        self.perSpawn = perSpawn
        self.ticsPerSpawn = ticsPerSpawn
        self.reset()
    def reset(self):
        self.timer = 0
    def spawn(self):
        self.timer += 1
        if self.timer >= int(self.ticsPerSpawn()):#200-kills
            for i in range(0,int(self.perSpawn())): #kills/10+1
                self.spawner()
                self.timer = 0

#FUNCTIONS

class Function:
    def __init__(self, x):
        self.x = x
    def calculate(self):
        return self.x()

class Linear(Function):
    def __init__(self, x, slope, intercept):
        Function.__init__(self, x)
        self.slope = slope
        self.intercept = intercept
    def calculate(self):
        return ( ( self.slope * self.x() ) + self.intercept )
    
class MinBounded(Function):
    def __init__(self, x, minimum):
        Function.__init__(self, x)
        self.minimum = minimum
    def calculate(self):
        x = self.x()
        if x < self.minimum: x = self.minimum
        return x

class MaxBounded(Function):
    def __init__(self, x, maximum):
        Function.__init__(self, x)
        self.maximum = maximum
    def calculate(self):
        x = self.x()
        if x > self.maximum: x = self.maximum
        return x

class Triangle(Function):
    def __init__(self, x, slope, intercept, midpoint):
        Function.__init__(self, x)
        self.slope = slope
        self.intercept = intercept
        self.midpoint = midpoint
    def calculate(self):
        x = self.x()
        if x <= self.midpoint:
            x = self.slope * x
        else:
            x = (-self.slope * x) + (2 * self.slope * self.midpoint)
        x += self.intercept
        return x

class LinearSpawner(Spawner):
    """
    """
    def __init__(self, spawner, stat, slope = .1, intercept = 1, tps_slope = -1, tps_intercept = 200):
        ps_function = Linear(stat, slope, intercept)
        perSpawn = ps_function.calculate
        tps_function = Linear(stat, tps_slope, tps_intercept)
        tps_function = MinBounded(tps_function.calculate, 1)
        ticsPerSpawn = tps_function.calculate
        Spawner.__init__(self, spawner, perSpawn, ticsPerSpawn)
        
class RandomSpawner(LinearSpawner):
    """
    """
    def __init__(self, spawner, stat, chance = .1, slope = .1, intercept = 1, tps_slope = -1, tps_intercept = 200):
        self._spawner = spawner
        self.chance = chance
        LinearSpawner.__init__(self, self.randSpawner, stat, slope, intercept, tps_slope, tps_intercept)
    def randSpawner(self):
        r = random.randrange(int(1/self.chance))
        if r == 0:
            self._spawner()

class TriangleSpawner(Spawner):
    """
    """
    def __init__(self, spawner, stat, slope = .1, intercept = 1, midpoint = 20):
        ps_function = Triangle(stat, slope, intercept, midpoint)
        perSpawn = ps_function.calculate
        tps_function = Triangle(stat, -1, 200, 100)
        tps_function = MaxBounded(tps_function.calculate, 200)
        tps_function = MinBounded(tps_function.calculate, 50)
        ticsPerSpawn = tps_function.calculate
        Spawner.__init__(self, spawner, perSpawn, ticsPerSpawn)

class TimerBurstSpawner:
    def __init__(self, spawner, stat, target, number, *args):
        self.target = target
        self.number = number
        self.spawner = spawner
        self.reset()
    def reset(self):
        self.timer = 0
    def spawn(self):
        self.timer += 1
        if self.timer == self.target:
            for i in range(self.number):
                self.spawner()
            self.timer = 0

class StatBurstSpawner:
    def __init__(self, spawner, stat, target, number):
        self.target = target
        self.number = number
        self.spawner = spawner
        self.stat = stat
        self.reset()
    def reset(self):
        self.done = False
    def spawn(self):
        if self.stat() >= self.target and not self.done:
            for i in range(self.number):
                self.spawner()
            self.done = True
